package team.first.movieapiv3.controller;

import cn.hutool.core.convert.Convert;
import io.swagger.annotations.ApiOperation;
import org.neo4j.ogm.cypher.BooleanOperator;
import org.neo4j.ogm.cypher.ComparisonOperator;
import org.neo4j.ogm.cypher.Filter;
import org.neo4j.ogm.cypher.Filters;
import org.neo4j.ogm.cypher.query.Pagination;
import org.neo4j.ogm.cypher.query.SortOrder;
import org.neo4j.ogm.metadata.FieldInfo;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import team.first.movieapiv3.dto.RequestMovie;
import team.first.movieapiv3.movie.GenreNode;
import team.first.movieapiv3.movie.MovieNode;
import team.first.movieapiv3.util.SessionFactoryUtil;
import team.first.movieapiv3.vo.ApiResponse;
import team.first.movieapiv3.vo.ApiResponsePaging;

import java.util.Collection;

/**
 * @Author: HAPPY
 * @Project_name: project
 * @Package_name: team.first.movieapiv3.controller
 * @Date: 2021/12/9 16:18
 * @Description:
 */
@RestController
public class MovieController {
    static SessionFactory sessionFactory = SessionFactoryUtil.getSessionFactory("team.first.movieapiv3.movie");

    /**
     * 1.2 获取指定编号的电影信息
     * 接口地址：GET /api/v3/movie/{movieId}
     */
    @ApiOperation("1.2 GET: 获取指定编号的电影信息")
    @GetMapping("/api/v3/movie/{movieId}")
    public ApiResponse<MovieNode> getMovieById(@PathVariable("movieId") Integer movieId) {
        ApiResponse<MovieNode> apiResponse = new ApiResponse<>();
        Session session = sessionFactory.openSession();
        MovieNode movieNode = session.load(MovieNode.class, movieId);

        apiResponse.setCode(200).setSuccess(true).setMessage("请求成功").setData(movieNode);
        return apiResponse;
    }

    /**
     * 2.3 根据条件分页获取指定的电影列表
     * 接口地址:POST /api/v3/movies
     */
    @PostMapping("/api/v3/movies")
    @ApiOperation("1.3 POST: 根据条件分页获取指定的电影列表")
    public ApiResponsePaging<Collection<MovieNode>> getStuff(RequestMovie requestMovie) {
        ApiResponsePaging<Collection<MovieNode>> responsePaging = new ApiResponsePaging<>();

        try {
            Session session = sessionFactory.openSession();

            Filters filters = new Filters();

            // 建立查询条件
            if (requestMovie.getOriginalTitle() != null) {
                //  加上"*"为模糊匹配，neo4j全栈开发，124页
                filters.add(new Filter("originalTitle", ComparisonOperator.LIKE, "*" + requestMovie.getOriginalTitle() + "*"));
            }

            if (requestMovie.getChineseTitle() != null) {
                // 用于将此筛选器附加到上一个筛选器的布尔运算符。
                // 如果筛选器不是列表中的第一个也是唯一一个筛选器，则BooleanOperator为必填项。
                Filter filter = new Filter("chineseTitle", ComparisonOperator.LIKE, "*" + requestMovie.getChineseTitle() + '*');
                filter.setBooleanOperator(BooleanOperator.AND);
                filters.add(filter);
            }

            if (requestMovie.getStartYear() != null) {
                Filter filter = new Filter("year", ComparisonOperator.GREATER_THAN_EQUAL, requestMovie.getStartYear());
                filter.setBooleanOperator(BooleanOperator.AND);
                filters.add(filter);
            }

            if (requestMovie.getEndYear() != null) {
                Filter filter = new Filter("year", ComparisonOperator.LESS_THAN_EQUAL, requestMovie.getEndYear());
                filter.setBooleanOperator(BooleanOperator.AND);
                filters.add(filter);
            }

            if (requestMovie.getRegion() != null) {
                Filter filter = new Filter("region", ComparisonOperator.LIKE, "*" + requestMovie.getRegion() + "*");
                filter.setBooleanOperator(BooleanOperator.AND);
                filters.add(filter);
            }

            if (requestMovie.getLanguage() != null) {
                Filter filter = new Filter("language", ComparisonOperator.LIKE, "*" + requestMovie.getLanguage() + "*");
                filter.setBooleanOperator(BooleanOperator.AND);
                filters.add(filter);
            }

            // 嵌套查询id，但是有问题
//            if (requestMovie.getGenreIds() != null) {
//                filter = new Filter("genres", ComparisonOperator.IN, requestMovie.getGenreIds());
//                filter.setBooleanOperator(BooleanOperator.AND);
//                filter.setNestedEntityTypeLabel("Genre");
//                filter.setOwnerEntityType(MovieNode.class);
//                filter.setNestedPropertyType(GenreNode.class);
//                filter.setNestedPropertyName("id");
//                filters.add(filter);
//            }

            Collection<MovieNode> movieNodeCollection = null;

            Pagination pagination = null;
            if (requestMovie.getPageNumber() != null) {
                pagination = new Pagination(requestMovie.getPageNumber() - 1, requestMovie.getPagerSize());
                responsePaging.setPageNumber(requestMovie.getPageNumber());
                responsePaging.setPageSize(requestMovie.getPagerSize());
            }

            // 排序
            if (requestMovie.getOrderField() != null) {
                // 根据排序规则排序，默认升序
                if (requestMovie.getOrderDirection() != null && "DESC".equalsIgnoreCase(requestMovie.getOrderDirection())) {
                    movieNodeCollection = session.loadAll(MovieNode.class, filters, new SortOrder(SortOrder.Direction.DESC, requestMovie.getOrderField()), pagination, 2);
                } else {
                    movieNodeCollection = session.loadAll(MovieNode.class, filters, new SortOrder(SortOrder.Direction.ASC, requestMovie.getOrderField()), pagination, 2);
                }
            } else {
                movieNodeCollection = session.loadAll(MovieNode.class, filters, pagination, 2);
            }
            responsePaging.setCode(200).setSuccess(true).setMessage("请求成功").setData(movieNodeCollection).setTotalRow(Convert.toInt(session.count(MovieNode.class, filters)));
        } catch (Exception e) {
            e.printStackTrace();
            responsePaging.setCode(500).setSuccess(false).setMessage("请求失败");
        }
        return responsePaging;
    }
}
